package com.sun.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sun.common.BaseContext;
import com.sun.common.CodeMsg;
import com.sun.common.Result;
import com.sun.common.SystemCrmlog;
import com.sun.dto.LoginMessage;
import com.sun.entity.Log;
import com.sun.entity.User;
import com.sun.service.UserService;
import com.sun.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @Project: hospitalDrugInformationManagement
 * @Author: 86178
 * @Date: 2023/2/7 10:32
 * @FileName: UserController
 * @Description: ""
 */
@Slf4j
@SuppressWarnings("all")
@RestController
@RequestMapping("/user")
@CrossOrigin
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    private JwtUtils jwtUtils;

    @Autowired
    private RedisUtils redisUtils;

    private final String codePre = "verifyCode";


    /*用户状态*/
    private final String normalUserStatus = "1";
    private final String lockUserStatus = "0";
    /*登录日志结果类型*/
    private final String successResult = "0";
    private final String nullUserResult = "1";
    private final String smsOverdueResult = "2";
    private final String smsErrorResult = "3";
    private final String pwdErrorResult = "4";
    private final String lockResult = "5";
    private Log loginLog = new Log();

    @GetMapping("sendMessage")
    public String getCode(@RequestParam("phone") String phone) {
        User userBean = userService.getUserByTel(phone);
        if (userBean == null) {
            return "400";
        }
        String code = ValidateCodeUtils.generateValidateCode(4).toString();
        if (SMSUtils.sendMessage("阿里云短信测试", "SMS_154950909", phone, code)) {
            redisUtils.add(codePre + phone, code, 5L, TimeUnit.MINUTES);
            return "200";
        } else {
            return "400";
        }
    }


    @PostMapping("/loginPassword")
    public Result<Map<String, Object>> loginPassword(@RequestBody LoginMessage loginMessage, HttpServletRequest request) {
        HashMap<String, Object> map = new HashMap<>();
//        if(request.getSession(true).getAttribute("verify_code")==null||!loginMessage.getCode().toUpperCase().equals(request.getSession(true).getAttribute("verify_code").toString().toUpperCase())){
//            map.put("msg", "验证码错误");
//            //获取用户真实的IP地址并设置登录时间
//            loginLog
//                    .setIp(HttpUtils.getIpAddress(request)).setType("账户登录")
//                    .setDateTime(LocalDateTime.now()).setResult("3").setLogRemark("验证码错误");
//            return Result.error(String.valueOf(map));
//        }

        //1、将页面提交的密码password进行md5加密处理
        String password = loginMessage.getPassword();
        password = DigestUtils.md5DigestAsHex(password.getBytes(StandardCharsets.UTF_8));


        //获取用户真实的IP地址并设置登录时间
        loginLog
                .setIp(HttpUtils.getIpAddress(request))
                .setDateTime(LocalDateTime.now());

        //获取用户信息
        loginLog.setType("账号登录").setAccount(loginMessage.getUsername());
        User userBean = userService.getUserByAccount(loginMessage.getUsername());


        if (null == userBean) {
            loginLog.setResult(nullUserResult).setLogRemark("尝试登录的账户并不存在");
            return Result.error(CodeMsg.ACCOUNT_NOT_FOUND);
        } else if (!userBean.getPassword().equals(password)) {
            userService.userToLoginLog(userBean, loginLog);
            loginLog.setResult(pwdErrorResult).setLogRemark("密码错误");
            return Result.error(CodeMsg.Password_NOT_FOUND);
        } else if (userBean.getStatus() == 0) {
            userService.userToLoginLog(userBean, loginLog);
            loginLog.setResult(lockResult).setLogRemark("该账户已锁定");
            return Result.error(CodeMsg.ACCOUNT_NOT_ACTIVATED);
        } else {
            userService.userToLoginLog(userBean, loginLog);
            loginLog.setResult(successResult).setLogRemark("用户登录成功");
            System.out.println(loginLog.toString());
            String token = jwtUtils.sign(loginMessage.getUsername());

            map.put("user", userBean);
            map.put("token", token);
            return Result.success(map);
        }
    }

    /**
     * 获取用户信息
     *
     * @return
     */
    @RequiresAuthentication
    @GetMapping("info")
    public Result info() {
        Long id = BaseContext.getCurrentId();
        User user = userService.getById(id);
        Map<String, Object> map = new HashMap<>();
        map.put("roles", user.getType());
        map.put("name", user.getNickName());
        map.put("id", user.getId());
        map.put("account", user.getAccount());
        map.put("sex", user.getSex());
        map.put("idNumber", user.getIdNumber());
        map.put("createTime", user.getCreateTime());
        map.put("email", user.getEmail());
        map.put("status", user.getStatus());
        map.put("tel", user.getTel());
        map.put("position", user.getPosition());
        map.put("avatar", user.getHeadImage());
        return Result.success(map);
    }


    @PostMapping("/loginSms")//未测试
    public Result<Map<String, Object>> loginSms(@RequestBody LoginMessage loginMessage) {
        User userBean = userService.getUserByTel(loginMessage.getUsername());
        String codeInRedis = redisUtils.get(codePre + loginMessage.getUsername());
        String code = loginMessage.getPassword();
        if (null == userBean) {
            return Result.error(CodeMsg.ACCOUNT_NOT_FOUND);
        }
        if (codeInRedis != null) {
            if (!code.equals(codeInRedis)) {
                return Result.error(CodeMsg.CAPTCHA_INVALID);
            }
            if (userBean.getStatus() == 0) {
                return Result.error(CodeMsg.ACCOUNT_NOT_ACTIVATED);
            }
            String token = jwtUtils.sign(loginMessage.getUsername());
            HashMap<String, Object> map = new HashMap<>();
            map.put("user",userBean);
            map.put("Authorization",token);
            return Result.success(map);
        }else {
            return Result.error(CodeMsg.CAPTCHA_EXPIRED);
        }
    }

//    /***
//     * 退出登入
//     * @param request
//     * @return
//     */
//    @PostMapping("/logout")
//    public Result<String> logout(HttpServletRequest request){
//        //清理Session中保存的当前登录员工的id
//        request.getSession().removeAttribute("employee");
//        return Result.success("退出成功");
//    }

    /**
     * 退出
     */
    @PostMapping("/logout")
    public Map<String, Object> logout() {
        Map<String, Object> result = new HashMap<>();
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        result.put("code", 200);
        result.put("msg", "您已安全退出系统");
        return result;
    }


    /**
     * 员工信息分页查询
     *
     * @param page
     * @param pageSize
     * @param name
     * @return
     */
    @RequiresAuthentication
    @GetMapping("/page")
    public Result<Page> page(int pageNum, int pageSize, String name, String position) {
        log.info("page = {},pageSize = {},name = {}", pageNum, pageSize, name);
        //构造分页构造器
        Page<User> pageInfo = new Page<>(pageNum, pageSize);
        //构造条件构造器
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        //添加过滤条件
        lambdaQueryWrapper.like(null != name, User::getNickName, name);
        lambdaQueryWrapper.like(null != position, User::getPosition, position);
        lambdaQueryWrapper.ne(User::getType, 0).ne(User::getType, 5);
        //添加排序条件
        lambdaQueryWrapper.orderByDesc(User::getUpdateTime).orderByDesc(User::getPosition);
        //执行查询
        userService.page(pageInfo, lambdaQueryWrapper);

        return Result.success(pageInfo);
    }

    /**
     * 员工信息分页查询
     *
     * @param page
     * @param pageSize
     * @param name
     * @return
     */
    @RequiresRoles("0")
    @RequiresAuthentication
    @GetMapping("/pageAdmin")
    public Result<Page> pageAdmin(int pageNum, int pageSize, String name) {
        log.info("page = {},pageSize = {},name = {}", pageNum, pageSize, name);
        //构造分页构造器
        Page<User> pageInfo = new Page<>(pageNum, pageSize);
        //构造条件构造器
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        //添加过滤条件
        lambdaQueryWrapper.like(null != name, User::getNickName, name);
        lambdaQueryWrapper.eq(User::getType, 5);
        //添加排序条件
        lambdaQueryWrapper.orderByDesc(User::getUpdateTime).orderByDesc(User::getPosition);
        //执行查询
        userService.page(pageInfo, lambdaQueryWrapper);

        return Result.success(pageInfo);
    }

    /**
     * 根据id查询员工信息
     * @param id
     * @return
     */
    @RequiresAuthentication
    @GetMapping("/{id}")
    public Result<User> getById(@PathVariable Long id){
        User user = userService.getById(id);
        if(user != null){
            return Result.success(user);
        }
        return Result.error(CodeMsg.NO_HANDLER_FOUND);
    }

    /**
     * 新增员工
     * @param user
     * @return
     */
    @SystemCrmlog(title = "用户管理模块", type = "INSERT", description = "新增用户")
    @RequiresRoles("0")
    @RequiresAuthentication
    @PostMapping("/save")
    public Result<String> save(@RequestBody User user) {
        //设置默认密码123456，并MD5加密
        String password = DigestUtils.md5DigestAsHex("123456".getBytes(StandardCharsets.UTF_8));
        user.setPassword(password);
        user.setStatus(1);
        if (user.getType() == 1) {
            user.setPosition("采购员");
        } else if (user.getType() == 2) {
            user.setPosition("库管员");
        } else if (user.getType() == 3) {
            user.setPosition("医生");
        } else if (user.getType() == 4) {
            user.setPosition("销售员");
        } else if (user.getType() == 5) {
            user.setPosition("管理员");
        }
        boolean flag = userService.save(user);
        if (flag) {
            return Result.success("新增员工成功");
        } else {
            return Result.error("新增员工失败");
        }
    }

    /**
     * 修改信息(修改基本信息，禁用状态，身份)
     * @param user
     * @return
     */
    @SystemCrmlog(title = "用户管理模块", type = "UPDATE", description = "修改用户信息信息")
    @RequiresAuthentication
    @PutMapping("/updateUser")//未测试
    public Result<String> updateUser(@RequestBody User user){

        boolean flag = userService.updateById(user);
        if (flag){
            return Result.success("修改成功");
        }else {
            return Result.error("修改失败");
        }

    }


    /**
     * 删除用户
     *
     * @param id
     * @return
     */
    @SystemCrmlog(title = "用户管理模块", type = "DELETE", description = "删除用户")
    @RequiresRoles("0")
    @RequiresAuthentication
    @DeleteMapping("/deleteUser/{id}")
    public Result<String> deleteUser(@PathVariable Long id) {
        boolean flag = userService.removeById(id);
        if (flag) {
            return Result.success();
        } else {
            return Result.error(CodeMsg.FORBIDDEN);
        }

    }

    /**
     * 查询所有采购员
     *
     * @return
     */
    @GetMapping("/list")
    public Result<List<User>> list() {
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(User::getType, 1);
        lambdaQueryWrapper.orderByAsc(User::getCreateTime);

        List<User> users = userService.list(lambdaQueryWrapper);

        return Result.success(users);
    }

    @GetMapping("/list2")
    public Result<List<User>> list2() {
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(User::getType, 2);
        lambdaQueryWrapper.orderByAsc(User::getCreateTime);

        List<User> users = userService.list(lambdaQueryWrapper);

        return Result.success(users);
    }

    @GetMapping("/list3")
    public Result<List<User>> list3() {
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(User::getType, 0).or().eq(User::getType, 5);
        lambdaQueryWrapper.orderByAsc(User::getCreateTime);

        List<User> users = userService.list(lambdaQueryWrapper);

        return Result.success(users);
    }

    /**
     * 导出用户数据
     *
     * @return
     */

    @GetMapping("/test")
    @RequiresAuthentication
    public User test() {
//        Subject subject = SecurityUtils.getSubject();
//        if (subject.isAuthenticated()) {
//            return "You are already logged in";
//        } else {
//            return "You are guest";
//        }
        return userService.getById(1);
    }
}
